home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / dos / fs / dskchckr.1 < prev    next >
Encoding:
Text File  |  1989-03-16  |  34.9 KB  |  953 lines

  1. Path: wugate!wucs1!uunet!lll-winken!ames!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i074:  diskchecker - check a disk for errors
  5. Message-ID: <12296@swan.ulowell.edu>
  6. Date: 16 Mar 89 19:21:40 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 942
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: chk@gpu.utcs.toronto.edu (C. Harald Koch)
  12. Posting-number: Volume 89, Issue 74
  13. Archive-name: dos/fs/diskchecker.1
  14.  
  15. DiskChecker reads through every sector on a disk reporting any errors
  16. encountered.
  17.  
  18. [uuencoded executable included.  ..Bob]
  19.  
  20. #    This is a shell archive.
  21. #    Remove everything above and including the cut line.
  22. #    Then run the rest of the file through sh.
  23. #----cut here-----cut here-----cut here-----cut here----#
  24. #!/bin/sh
  25. # shar:    Shell Archiver
  26. #    Run the following text with /bin/sh to create:
  27. #    README
  28. #    makefile
  29. #    devinfo.h
  30. #    break.c
  31. #    diskchecker.c
  32. #    getdevinfo.c
  33. #    getopt.c
  34. #    diskchecker.uu
  35. # This archive created: Thu Mar 16 14:19:46 1989
  36. cat << \SHAR_EOF > README
  37. DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.
  38.  
  39.     C. Harald Koch
  40.     260 Wellesley St. E.
  41.     Toronto, ON Canada
  42.     M4X 1G6
  43.  
  44.     chk@gpu.utcs.toronto.edu
  45.  
  46.     Permission is granted to distribute, modify, or use this program in
  47.     whole or in part, so long as this copyright notice remains intact.
  48.     This program may not be sold for profit without permission.
  49.  
  50. Thanks to Dave Haynie for the original idea, which was based on his original
  51. version of DiskSalv. Some of the code is originally from that program.
  52.  
  53. Thanks to Matt Dillon for his SIGBREAK routines (break.c) and for reams of
  54. insight into the innards of Amiga programming.
  55.  
  56. What is DiskChecker?
  57.  
  58. I often copy software onto floppies to take home from work or for archival
  59. purposes. Every once in a while, I would find that something had been
  60. written incorrectly to disk. Finally, I got tired of this, so I wrote
  61. DiskChecker.
  62.  
  63. DiskChecker will read every sector on a disk, reporting any read errors
  64. found. To check a disk:
  65.  
  66.     1> DiskChecker [-v|q] <device-name>
  67.  
  68. where device-name is the name of a disk device (DF0:, FF0:, DH0:, RAD:, etc).
  69. DiskChecker will print statistics about the device, and then read through
  70. each sector on the disk. It will report any errors encountered by error
  71. number. In addition, if the error is a valid trackdisk.device error,
  72. DiskChecker will print a descriptive error message also.  DiskChecker will
  73. abort if a CTRL-C or CTRL-D is typred.
  74.  
  75. OPTIONS:
  76.     -q    - perform check quietly; only report errors encountered.
  77.     -v    - perform check verbosely; print every sector checked.
  78.  
  79. BEWARE: DiskChecker tries to make certain sanity checks about devices being
  80. checked. It will not let you check CON:, for example. HOWEVER, these checks
  81. are far from perfect. You will crash your machine if you try to check SER:,
  82. PAR:, or PRT:, for example. Make sure the device statistics printed look
  83. reasonable before proceeding.
  84.  
  85. COMPILATION NOTES:
  86.  
  87. DiskChecker uses some structures that are new to the 1.3 header files. (The
  88. strucures have always existed; the header files have been reorganized to
  89. make accessing them from C easier). It currently requires libraries/dos.h,
  90. libraries/dosextens.h, and libraries/filehandler.h from the 1.3Includes disk.
  91.     
  92.  
  93. Please send me any bug reports, enhancements, suggestions, jelly beans, etc.
  94.  
  95.     C. Harald Koch
  96.     09-March-89
  97. SHAR_EOF
  98. cat << \SHAR_EOF > makefile
  99. # Makefile for DiskChecker using Aztec C 3.6a
  100. #
  101. SRCS    = diskchecker.c getdevinfo.c break.c getopt.c
  102. OBJS    = diskchecker.o getdevinfo.o break.o getopt.o
  103.  
  104. CFLAGS    = +p
  105. LFLAGS    =
  106. LIBS    = -lcl32
  107.  
  108. all : diskchecker
  109.  
  110. diskchecker : $(OBJS)
  111.     ln $(LFLAGS) -o diskchecker $(OBJS) $(LIBS)
  112. SHAR_EOF
  113. cat << \SHAR_EOF > devinfo.h
  114. struct MyDevInfo {
  115.     char *DeviceName;        /* exec device name */
  116.     ULONG Unit;            /* exec unit number */
  117.     ULONG DeviceFlags;        /* flags to OpenDevice */
  118.     ULONG BlockSize;        /* in bytes */
  119.     ULONG Surfaces;        /* # of heads */
  120.     ULONG BlocksPerTrack;    /* blocks per track (not cylinder) */
  121.     ULONG Reserved;        /* number of reserved blocks at beginning */
  122.     ULONG PreAlloc;        /* number of reserved blocks at end */
  123.     ULONG LowCyl;        /* first cylinder */
  124.     ULONG HighCyl;        /* last cylinder */
  125.     ULONG BufMemType;        /* type of memory for buffers */
  126.     ULONG DosType;        /* 0x444F5300 or 0x444F5301 */
  127. };
  128.  
  129. extern    struct MyDevInfo *getDevInfo();
  130. SHAR_EOF
  131. cat << \SHAR_EOF > break.c
  132. /*-
  133.  *    break.c
  134.  *    Amiga BREAK signal handling
  135.  *
  136.  *    Thanks to Matt Dillon (dillon@postgres.berkeley.edu) for these
  137.  *    routines, which are part of his support library.
  138.  *
  139. -*/
  140.  
  141. #include    <libraries/dos.h>
  142.  
  143. extern int Enable_Abort;
  144. extern    long    SetSignal();
  145.  
  146. disablebreak()
  147. {
  148.     Enable_Abort = 0;
  149. }
  150.  
  151. enablebreak()
  152. {
  153.     Enable_Abort = 1;
  154. }
  155.  
  156.  
  157. /*-
  158.  * CHECKBREAK()
  159.  *
  160.  *    Return    1 = break pressed,
  161.  *        0 = break not pressed
  162. -*/
  163.  
  164. #define SBF  (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)
  165.  
  166. checkbreak()
  167. {
  168.     return (SetSignal(0L,0L) & SBF) ? 1 : 0;
  169. }
  170. SHAR_EOF
  171. cat << \SHAR_EOF > diskchecker.c
  172. /*-
  173.  * DiskChecker - check a floppy disk for errors
  174.  *
  175.  * DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.
  176.  *
  177.  *    DiskChecker is based on the original version of DiskSalv by Dave
  178.  *     Haynie. The DiskIO code is originally his.
  179.  *
  180.  * DiskChecker is freely redistributable, provided no fee is charged etc.
  181.  *
  182.  *
  183.  * SYNOPSIS:
  184.  *    DiskChecker dfn:
  185.  *
  186.  * Will check the floppy in drive n for any errors at the track and sector level.
  187.  *
  188.  * Compiles under Aztec C 3.4 with 32 bit integers.
  189.  *
  190.  *
  191. -*/
  192.  
  193. #include    <exec/types.h>
  194. #include    <exec/exec.h>
  195. #include    <devices/trackdisk.h>
  196. #include    <libraries/dos.h>
  197. #include    <libraries/dosextens.h>
  198. #include    <ctype.h>
  199. #include    <stdio.h>
  200.  
  201. #include    <functions.h>
  202. #include    "devinfo.h"
  203.  
  204. extern    void *    CreateExtIO();
  205.  
  206. char            prog_version[] = "1.0";
  207.  
  208. char           *td_errors[] = {
  209.      /* 20 TDERR_NotSpecified     */ "Undetermined Error",
  210.      /* 21 TDERR_NoSecHdr     */ "Couldn't Find Sector Header",
  211.      /* 22 TDERR_BadSecPreamble     */ "Error in Sector Preamble",
  212.      /* 23 TDERR_BadSecID     */ "Error in Sector Identifier",
  213.      /* 24 TDERR_BadHdrSum     */ "Bad Header Field Checksum",
  214.      /* 25 TDERR_BadSecSum     */ "Bad Sector Data Field Checksum",
  215.      /* 26 TDERR_TooFewSecs     */ "Incorrect Number of Sectors on Track",
  216.      /* 27 TDERR_BadSecHdr     */ "Unable to Read Sector Header",
  217.      /* 28 TDERR_WriteProt     */ "Disk is Write Protected",
  218.      /* 29 TDERR_DiskChanged     */ "Disk Changed or not Present",
  219.      /* 30 TDERR_SeekError     */ "Seek Error While Verifying Seek Position",
  220.      /* 31 TDERR_NoMem         */ "Not Enough Memory",
  221.      /* 32 TDERR_BadUnitNum     */ "Bad Unit Number",
  222.      /* 33 TDERR_BadDriveType     */ "Bad Drive Type",
  223.      /* 34 TDERR_DriveInUse     */ "Drive In Use",
  224.      /* 35 TDERR_PostReset     */ "TDERR_PostReset"
  225. };
  226.  
  227. #define    LOWTDERR    20
  228. #define    HIGHTDERR    35
  229.  
  230. #define    NUM_CYLS    (mdi->HighCyl - mdi->LowCyl + 1)
  231. #define DISK_SIZE    (mdi->Surfaces*NUM_CYLS*mdi->BlocksPerTrack)
  232. #define READOK        0
  233.  
  234. LONG            diskChangeCount = 0;    /* Checks for changed disk */
  235. int             verbose = 0;    /* print every sector? */
  236. int             summary = 1;    /* print every cylinder? */
  237.  
  238.  
  239. static void
  240. MotorOff(req)
  241. struct IOExtTD *req;
  242. {
  243.     req->iotd_Req.io_Length = 0;
  244.     req->iotd_Req.io_Command = TD_MOTOR;
  245.     DoIO(req);
  246. }
  247.  
  248.  
  249. static void
  250. InitDisk(req)
  251. struct IOExtTD *req;
  252. {
  253.     req->iotd_Req.io_Command = TD_CHANGENUM;
  254.     DoIO(req);
  255.     diskChangeCount = req->iotd_Req.io_Actual;
  256. }
  257.  
  258.  
  259. BYTE
  260. ReadBuf(req, buf, sect, len)
  261. struct IOExtTD *req;
  262. char           *buf;
  263. ULONG           sect;
  264. ULONG           len;
  265. {
  266.     req->iotd_Req.io_Length = len;
  267.     req->iotd_Req.io_Data = (APTR) buf;
  268.     req->iotd_Req.io_Command = ETD_READ;
  269.     req->iotd_Count = diskChangeCount;
  270.     req->iotd_Req.io_Offset = len * sect;
  271.     DoIO(req);
  272.     return (req->iotd_Req.io_Error);
  273. }
  274.  
  275.  
  276. int
  277. checkDisk(mdi)
  278. struct MyDevInfo *mdi;
  279. {
  280.     ULONG           sect, head, block, cylinder;    /* Current block */
  281.     BYTE            result;
  282.     struct IOExtTD *diskreq = NULL;
  283.     struct MsgPort *diskport = NULL;
  284.     char           *buf = NULL;
  285.  
  286.     if ((diskport = (struct MsgPort *) CreatePort("diskreq.port", 0)) == NULL) {
  287.     printf("ERROR: Cannot create message port\n");
  288.     goto error;
  289.     }
  290.  
  291.     if ((diskreq = (struct IOExtTD *)
  292.      CreateExtIO(diskport, sizeof(struct IOExtTD))) == NULL) {
  293.     printf("ERROR: Cannot create I/O port\n");
  294.     goto error;
  295.     }
  296.  
  297.     if ((buf = (char *) AllocMem(mdi->BlockSize, mdi->BufMemType)) == NULL)
  298.     goto error;
  299.  
  300.     if (OpenDevice(mdi->DeviceName, mdi->Unit, diskreq, 0)) {
  301.     printf("ERROR: Cannot open TrackDisk device\n");
  302.     goto error;
  303.     }
  304.  
  305.     InitDisk(diskreq);
  306.  
  307.     sect = 0;
  308.     printf("\2330 p");        /* turn cursor off for faster rendering */
  309.  
  310.     for (cylinder = mdi->LowCyl; cylinder <= mdi->HighCyl; cylinder++) {
  311.     for (head = 0; head < mdi->Surfaces; head++) {
  312.         for (block = 0; block < mdi->BlocksPerTrack; block++, sect++) {
  313.  
  314.         if ((result = ReadBuf(diskreq, buf, sect, mdi->BlockSize)) != READOK) {
  315.             printf(" Block %6d (C:%04d H:%d S:%02d) ", sect,
  316.                cylinder, head, block);
  317.             if (result >= LOWTDERR && result <= HIGHTDERR) {
  318.             printf(" Error %2d: %s\n", result, td_errors[result - LOWTDERR]);
  319.             }
  320.             else {
  321.             printf("Error %2d: Unknown Trackdisk Error\n", result);
  322.             }
  323.         }
  324.         else {
  325.             if (verbose || (summary && head == 0 && block == 0)) {
  326.             printf(" Block %6d (C:%04d H:%d S:%02d) ", sect,
  327.                    cylinder, head, block);
  328.             printf("(OK)\233K\r");
  329.             }
  330.         }
  331.         fflush(stdout);
  332.  
  333.         if (checkbreak()) {
  334.             printf("\nBREAK detected!\n");
  335.             printf("\233 p"); /* turn cursor back on */
  336.             goto error;
  337.         }
  338.         }
  339.     }
  340.     }
  341.     printf("\233 p\n");
  342.  
  343. error:
  344.     if (buf != NULL)
  345.     FreeMem(buf, mdi->BlockSize);
  346.     if (diskreq != NULL) {
  347.     MotorOff(diskreq);
  348.     CloseDevice(diskreq);
  349.     DeleteExtIO(diskreq, sizeof(struct IOExtTD));
  350.     }
  351.     if (diskport != NULL)
  352.     DeletePort(diskport);
  353.  
  354.     return 0;
  355. }
  356.  
  357.  
  358. usage(s)
  359. char           *s;
  360. {
  361.     fprintf(stderr, "usage: %s [-v|q] <dos-device-name>\n", s);
  362. }
  363.  
  364. extern    int    getopt();
  365. extern    int    optind;
  366. extern    char *optarg;
  367.  
  368. int
  369. main(argc, argv)
  370. int             argc;
  371. char           *argv[];
  372. {
  373.     char            stat;
  374.     int             c;
  375.     extern char    *optarg;
  376.     char            name[20];
  377.     int             len;
  378.     struct MyDevInfo *mdi;
  379.  
  380.     disablebreak();
  381.  
  382.     printf("\nDiskChecker %s Copyright 1989 C. Harald Koch\n\n", prog_version);
  383.  
  384.     while((c = getopt(argc, argv, "vq")) != EOF) {
  385.     switch(c) {
  386.     case 'v':        /* run verbosely; print every sector */
  387.         verbose = 1;
  388.         break;
  389.     case 'q':        /* run quitely; only print errors */
  390.         verbose = summary = 0;
  391.         break;
  392.     default:
  393.         usage(argv[0]);
  394.         enablebreak();
  395.         exit(20);
  396.     }
  397.     }
  398.  
  399.     if (optind != argc - 1) {
  400.     usage(argv[0]);
  401.     enablebreak;
  402.     exit(10);
  403.     }
  404.  
  405.     strcpy(name, argv[optind]);
  406.     len = strlen(name);
  407.     if (name[len - 1] == ':') {
  408.     name[len - 1] = '\0';
  409.     len--;
  410.     }
  411.  
  412.     touppers(name);
  413.  
  414.     if ((mdi = getDevInfo(name)) != NULL) {
  415.     printf("DEVICE     =    %s   (%s)\n", mdi->DeviceName, name);
  416.     printf("UNIT       =    %5ld    FLAGS      =    %5ld\n", mdi->Unit, mdi->DeviceFlags);
  417.     printf("HEADS      =    %5ld    SECTORS    =    %5ld\n", mdi->Surfaces, mdi->BlocksPerTrack);
  418.     printf("LOCYL      =    %5ld    HICYL      =    %5ld\n", mdi->LowCyl, mdi->HighCyl);
  419.     printf("LOBLOCK    =    %5ld    HIBLOCK    =    %5ld\n",
  420.            mdi->LowCyl * mdi->Surfaces * mdi->BlocksPerTrack,
  421.            (mdi->HighCyl + 1) * mdi->Surfaces * mdi->BlocksPerTrack - 1);
  422.     printf("RESERVED   =    %5ld    MEMTYPE    =    %5ld\n", mdi->Reserved, mdi->BufMemType);
  423.     printf("FILESYS    =    %5s    DISK SIZE  =    %5ld\n",
  424.            (mdi->DosType == 0x444f5300) ? "OFS" : "FFS",
  425.            (mdi->HighCyl - mdi->LowCyl + 1) * mdi->Surfaces * mdi->BlocksPerTrack);
  426.  
  427.     printf("\nShould I Continue? [y] ");
  428.     if ((c = getchar()) != 'y' && c != 'Y' && c != '\n') {
  429.         printf("Aborting...\n");
  430.         exit(20);
  431.     }
  432.  
  433.     stat = checkDisk(mdi);
  434.  
  435.     enablebreak();
  436.     exit(stat);
  437.  
  438.     }
  439.     else {
  440.     printf("device not found (or device is not a disk device)\n");
  441.     enablebreak();
  442.     exit(20);
  443.     }
  444. }
  445. SHAR_EOF
  446. cat << \SHAR_EOF > getdevinfo.c
  447. /*-
  448.  * getdevinfo.c - get filesystem information about a disk device
  449.  *
  450.  * DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.
  451.  *
  452. -*/
  453.  
  454. #include    "libraries/dos.h"
  455. #include    "libraries/dosextens.h"
  456. #include    "libraries/filehandler.h"
  457. #include    <exec/memory.h>
  458.  
  459. #include    <ctype.h>
  460. #include    <stdio.h>
  461.  
  462. #include    "devinfo.h"
  463.  
  464. extern struct DosLibrary *DOSBase;
  465. extern void    *AllocMem();
  466.  
  467. #define CTOB(x) (void *)(((long)(x))>>2)    /* BCPL conversion */
  468. #define BTOC(x) (void *)(((long)(x))<<2)
  469.  
  470. touppers(s)
  471. char           *s;
  472. {
  473.     while (*s) {
  474.     *s = (islower(*s)) ? toupper(*s) : *s;
  475.     s++;
  476.     }
  477. }
  478.  
  479. void
  480. BtoCStr(cstr, bstr)
  481. char           *cstr;
  482. BPTR            bstr;
  483. {
  484.     char           *bstr2;
  485.     int             i;
  486.  
  487.     bstr2 = BTOC(bstr);
  488.     for (i = 0; i < bstr2[0]; i++) {
  489.     cstr[i] = bstr2[i + 1];
  490.     }
  491.     cstr[i] = '\0';
  492. }
  493.  
  494.  
  495. struct MyDevInfo *
  496. getDevInfo(name)
  497. char           *name;
  498. {
  499.     struct RootNode *root;
  500.     struct DosInfo *info;
  501.     struct DeviceNode *dnode;
  502.     struct FileSysStartupMsg *fsmsg;
  503.     struct DosEnvec *env;
  504.     long            unit;
  505.     char            dosname[20];
  506.     char            execname[256];
  507.     long            flags;
  508.     struct MyDevInfo *mdi;
  509.     root = (struct RootNode *) DOSBase->dl_Root;
  510.     info = (struct DosInfo *) BTOC(root->rn_Info);
  511.     dnode = (struct DeviceNode *) BTOC(info->di_DevInfo);
  512.  
  513.     for (; dnode != NULL;) {
  514.     if (dnode->dn_Type == DLT_DEVICE) {
  515.         BtoCStr(dosname, dnode->dn_Name);
  516.         if (strcmp(name, dosname) == 0) {
  517.         /* found it! */
  518.         fsmsg = (struct FileSysStartupMsg *) BTOC(dnode->dn_Startup);
  519.         if (fsmsg != NULL) {
  520.             char           *bcplname;
  521.             long            namelen;
  522.  
  523.             mdi = AllocMem(sizeof(*mdi), MEMF_CLEAR);
  524.             bcplname = BTOC(fsmsg->fssm_Device);
  525.             namelen = bcplname[0] + 1;
  526.             mdi->DeviceName = AllocMem(namelen, 0L);
  527.             BtoCStr(mdi->DeviceName, fsmsg->fssm_Device);
  528.             mdi->Unit = fsmsg->fssm_Unit;
  529.             mdi->DeviceFlags = fsmsg->fssm_Flags;
  530.             env = BTOC(fsmsg->fssm_Environ);
  531.             mdi->BlockSize = env->de_SizeBlock * 4;
  532.             mdi->Surfaces = env->de_Surfaces;
  533.             mdi->BlocksPerTrack = env->de_BlocksPerTrack;
  534.             mdi->Reserved = env->de_Reserved;
  535.             mdi->PreAlloc = env->de_PreAlloc;
  536.             mdi->LowCyl = env->de_LowCyl;
  537.             mdi->HighCyl = env->de_HighCyl;
  538.             if (env->de_TableSize >= 12) {
  539.             mdi->BufMemType = env->de_BufMemType;
  540.             }
  541.             else {
  542.             mdi->BufMemType = MEMF_CHIP;
  543.             }
  544.             if (env->de_TableSize >= 16) {
  545.             mdi->DosType = env->de_DosType;
  546.             }
  547.             else {
  548.             mdi->DosType = 0x444f5300;
  549.             }
  550.  
  551.             return mdi;
  552.         }
  553.         }
  554.     }
  555.     dnode = (struct DeviceNode *) BTOC(dnode->dn_Next);
  556.     }
  557.     return NULL;
  558. }
  559. SHAR_EOF
  560. cat << \SHAR_EOF > getopt.c
  561. /*-
  562. **    @(#)getopt.c    2.5 (smail) 9/15/87
  563. -*/
  564.  
  565. /*-
  566.  * Here's something you've all been waiting for:  the AT&T public domain
  567.  * source for getopt(3).  It is the code which was given out at the 1985
  568.  * UNIFORUM conference in Dallas.  I obtained it by electronic mail
  569.  * directly from AT&T.  The people there assure me that it is indeed
  570.  * in the public domain.
  571.  *
  572.  * There is no manual page.  That is because the one they gave out at
  573.  * UNIFORUM was slightly different from the current System V Release 2
  574.  * manual page.  The difference apparently involved a note about the
  575.  * famous rules 5 and 6, recommending using white space between an option
  576.  * and its first argument, and not grouping options that have arguments.
  577.  * Getopt itself is currently lenient about both of these things White
  578.  * space is allowed, but not mandatory, and the last option in a group can
  579.  * have an argument.  That particular version of the man page evidently
  580.  * has no official existence, and my source at AT&T did not send a copy.
  581.  * The current SVR2 man page reflects the actual behavor of this getopt.
  582.  * However, I am not about to post a copy of anything licensed by AT&T.
  583. -*/
  584.  
  585.  
  586. /* LINTLIBRARY */
  587. #define NULL    0
  588. #define EOF    (-1)
  589. #define ERR(s, c)    if(opterr){\
  590.     extern int write();\
  591.     char errbuf[2];\
  592.     errbuf[0] = c; errbuf[1] = '\n';\
  593.     (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  594.     (void) write(2, s, (unsigned)strlen(s));\
  595.     (void) write(2, errbuf, 2);}
  596.  
  597. extern char    *index();
  598.  
  599. int             opterr = 1;
  600. int             optind = 1;
  601. int             optopt;
  602. char           *optarg;
  603.  
  604. int
  605. getopt(argc, argv, opts)
  606. int             argc;
  607. char          **argv, *opts;
  608. {
  609.     static int      sp = 1;
  610.     register int    c;
  611.     register char  *cp;
  612.  
  613.     if (sp == 1)
  614.     if (optind >= argc ||
  615.         argv[optind][0] != '-' || argv[optind][1] == '\0')
  616.         return (EOF);
  617.     else if (strcmp(argv[optind], "--") == NULL) {
  618.         optind++;
  619.         return (EOF);
  620.     }
  621.     optopt = c = argv[optind][sp];
  622.     if (c == ':' || (cp = index(opts, c)) == NULL) {
  623.     ERR(": illegal option -- ", c);
  624.     if (argv[optind][++sp] == '\0') {
  625.         optind++;
  626.         sp = 1;
  627.     }
  628.     return ('?');
  629.     }
  630.     if (*++cp == ':') {
  631.     if (argv[optind][sp + 1] != '\0')
  632.         optarg = &argv[optind++][sp + 1];
  633.     else if (++optind >= argc) {
  634.         ERR(": option requires an argument -- ", c);
  635.         sp = 1;
  636.         return ('?');
  637.     }
  638.     else
  639.         optarg = argv[optind++];
  640.     sp = 1;
  641.     }
  642.     else {
  643.     if (argv[optind][++sp] == '\0') {
  644.         sp = 1;
  645.         optind++;
  646.     }
  647.     optarg = NULL;
  648.     }
  649.     return (c);
  650. }
  651. SHAR_EOF
  652. cat << \SHAR_EOF > diskchecker.uu
  653.  
  654. begin 644 diskchecker
  655. M```#\P`````````#``````````(```I:````K0```!D```/I```*6D[Z%!I5`
  656. M;F1E=&5R;6EN960@17)R;W(`0V]U;&1N)W0@1FEN9"!396-T;W(@2&5A9&5R3
  657. M`$5R<F]R(&EN(%-E8W1O<B!0<F5A;6)L90!%<G)O<B!I;B!396-T;W(@261E<
  658. M;G1I9FEE<@!"860@2&5A9&5R($9I96QD($-H96-K<W5M`$)A9"!396-T;W(@O
  659. M1&%T82!&:65L9"!#:&5C:W-U;0!);F-O<G)E8W0@3G5M8F5R(&]F(%-E8W1O6
  660. M<G,@;VX@5')A8VL`56YA8FQE('1O(%)E860@4V5C=&]R($AE861E<@!$:7-KQ
  661. M(&ES(%=R:71E(%!R;W1E8W1E9`!$:7-K($-H86YG960@;W(@;F]T(%!R97-E7
  662. M;G0`4V5E:R!%<G)O<B!7:&EL92!697)I9GEI;F<@4V5E:R!0;W-I=&EO;@!.K
  663. M;W0@16YO=6=H($UE;6]R>0!"860@56YI="!.=6UB97(`0F%D($1R:79E(%1Y@
  664. M<&4`1')I=F4@26X@57-E`%1$15)27U!O<W1297-E=```3E4``$CG,`(@;0`(5
  665. M0J@`)"!M``@Q?``)`!PO+0`(3KD``"A46$],WT`,3EU.=4Y5``!(YS`"(&T`Y
  666. M"#%\``T`'"\M``A.N0``*%183R!M``@CZ``@````1$S?0`Q.74YU3E4``$CGG
  667. M,`(@;0`((6T`%``D(&T`""%M``P`*"!M``@Q?(`"`!P@;0`((7D```!$`#`@'
  668. M;0`((BT`$"`M`!1.N0``);0A0``L+RT`"$ZY```H5%A/(&T`"!`H`!](@$C`L
  669. M3-]`#$Y=3G5.5?_B2.<P`D*M_^I"K?_F0JW_XD*G2'H"EDZY```FKE!/*T#_M
  670. MYF802'H"D4ZY```91%A/8``"%DAX`#@O+?_F3KD``">R4$\K0/_J9A!(>@*.(
  671. M3KD``!E$6$]@``'P(&T`""\H`"@@;0`(+R@`#$ZY```H/E!/*T#_XF<``=!"Z
  672. MIR\M_^H@;0`(+R@`!"!M``@O$$ZY```HT$_O`!!*@&<02'H"6TZY```91%A/H
  673. M8``!GB\M_^I.NOZP6$]"K?_\2'H"8DZY```91%A/(&T`""MH`"#_\&```5I"P
  674. MK?_X8``!/D*M__1@``$B(&T`""\H``PO+?_\+RW_XB\M_^I.NOZ:3^\`$!M`"
  675. M_^]G>B\M__0O+?_X+RW_\"\M__Q(>@(+3KD``!E$3^\`%`PM`!3_[VT\#"T`U
  676. M(__O;C00+?_O2(!(P)"\````%.6`0?D````$+S`(`!`M_^](@$C`+P!(>@'JO
  677. M3KD``!E$3^\`#&`6$"W_[TB`2,`O`$AZ`>!.N0``&4103V!&2KD```!(9A1*I
  678. MN0```$QG-DJM__AF,$JM__1F*B\M__0O+?_X+RW_\"\M__Q(>@'*3KD``!E$5
  679. M3^\`%$AZ`=U.N0``&4183TAX__](>0```09.N0``'X!03TZY```-^$J`9QI(G
  680. M>@&]3KD``!E$6$](>@'#3KD``!E$6$]@3%*M__12K?_\(&T`""`M__2PJ``4M
  681. M90#^TE*M__@@;0`(("W_^+"H`!!E`/ZV4JW_\"!M``@@+?_PL*@`)&,`_II(#
  682. M>@%Y3KD``!E$6$]*K?_B9Q0@;0`(+R@`#"\M_^).N0``*(I03TJM_^IG)B\MH
  683. M_^I.NOS&6$\O+?_J3KD``":,6$](>``X+RW_ZDZY```G_%!/2JW_YF<,+RW_O
  684. MYDZY```G1EA/<`!,WT`,3EU.=61I<VMR97$N<&]R=`!%4E)/4CH@0V%N;F]T#
  685. M(&-R96%T92!M97-S86=E('!O<G0*`$524D]2.B!#86YN;W0@8W)E871E($DO[
  686. M3R!P;W)T"@!%4E)/4CH@0V%N;F]T(&]P96X@5')A8VM$:7-K(&1E=FEC90H`1
  687. MFS`@<``@0FQO8VL@)39D("A#.B4P-&0@2#HE9"!3.B4P,F0I(``@17)R;W(@-
  688. M)3)D.B`E<PH`17)R;W(@)3)D.B!5;FMN;W=N(%1R86-K9&ES:R!%<G)O<@H`:
  689. M($)L;V-K("4V9"`H0SHE,#1D($@Z)60@4SHE,#)D*2``*$]+*9M+#0`*0E)%I
  690. M04L@9&5T96-T960A"@";('``FR!P"@!.50``2.<P`B\M``A(>@`:2'D```$<;
  691. M3KD``!+B3^\`#$S?0`Q.74YU=7-A9V4Z("5S(%LM=GQQ72`\9&]S+61E=FECS
  692. M92UN86UE/@H`3E7_WDCG,`).N0``#<A(>0````!(>@+^3KD``!E$4$](>@,BE
  693. M+RT`#"\M``A.N0``#B)/[P`,*T#_^K"\_____V=0("W_^F`Z(_P````!````0
  694. M2&`\0KD```!,0KD```!(8"X@;0`,+Q!.NO]*6$].N0``#=Y(>``43KD``"/"^
  695. M6$]@#I"\````<6?*6X!GNF#28(X@+0`(4X"PN0```%1G'B!M``PO$$ZZ_PQ8,
  696. M3T'Y```-WDAX``I.N0``(\)83R`Y````5.6`(&T`#"\P"`!(;?_F3KD``!$\1
  697. M4$](;?_F3KD``!%,6$\K0/_B("W_XD'M_^4,,``Z"`!F$"`M_^)![?_E0C`(^
  698. M`%.M_^)(;?_F3KD```LX6$](;?_F3KD```OL6$\K0/_>9P`!QDAM_^8@;?_>E
  699. M+Q!(>@(13KD``!E$3^\`#"!M_]XO*``((&W_WB\H``1(>@(.3KD``!E$3^\`$
  700. M#"!M_]XO*``4(&W_WB\H`!!(>@(>3KD``!E$3^\`#"!M_]XO*``D(&W_WB\HH
  701. M`"!(>@(N3KD``!E$3^\`#"!M_]X@*``D4H`@;?_>(B@`$$ZY```EM"!M_]XB8
  702. M*``43KD``"6T4X`O`"!M_]X@*``@(&W_WB(H`!!.N0``);0@;?_>(B@`%$ZYC
  703. M```EM"\`2'H!_DZY```91$_O``P@;?_>+R@`*"!M_]XO*``82'H"#DZY```9K
  704. M1$_O``P@;?_>("@`)"!M_]Z0J``@4H`@;?_>(B@`$$ZY```EM"!M_]XB*``4D
  705. M3KD``"6T+P`@;?_>#*A$3U,``"QF"$'Z`AT@"&`&0?H"&2`(+P!(>@'@3KD`L
  706. M`!E$3^\`#$AZ`@=.N0``&4183TAY````\$ZY```1CEA/*T#_^K"\````>6<L7
  707. M#*T```!9__IG(@RM````"O_Z9QA(>@'F3KD``!E$6$](>``43KD``"/"6$\O9
  708. M+?_>3KKY*%A/&T#__TZY```-WA`M__](@$C`+P!.N0``(\)83V`>2'H!LTZYM
  709. M```91%A/3KD```W>2'@`%$ZY```CPEA/3-]`#$Y=3G4*1&ES:T-H96-K97(@L
  710. M)7,@0V]P>7)I9VAT(#$Y.#D@0RX@2&%R86QD($MO8V@*"@!V<0!$159)0T4@9
  711. M("`@(#T@("`@)7,@("`H)7,I"@!53DE4("`@("`@(#T@("`@)35L9"`@("!&U
  712. M3$%'4R`@("`@(#T@("`@)35L9`H`2$5!1%,@("`@("`]("`@("4U;&0@("`@D
  713. M4T5#5$]24R`@("`]("`@("4U;&0*`$Q/0UE,("`@("`@/2`@("`E-6QD("`@>
  714. M($A)0UE,("`@("`@/2`@("`E-6QD"@!,3T),3T-+("`@(#T@("`@)35L9"`@W
  715. M("!(24),3T-+("`@(#T@("`@)35L9`H`4D5315)6140@("`]("`@("4U;&0@T
  716. M("`@345-5%E012`@("`]("`@("4U;&0*`$9)3$5365,@("`@/2`@("`E-7,@[
  717. M("`@1$E32R!325I%("`]("`@("4U;&0*`$]&4P!&1E,`"E-H;W5L9"!)($-O2
  718. M;G1I;G5E/R!;>5T@`$%B;W)T:6YG+BXN"@!D979I8V4@;F]T(&9O=6YD("AOA
  719. M<B!D979I8V4@:7,@;F]T(&$@9&ES:R!D979I8V4I"@!.50``2.<P`B!M``A*A
  720. M$&=$(&T`"!`02(!(P$'Y````;P@P``$(`&<6(&T`"!`02(!(P"\`3KD``!%>1
  721. M6$]@"B!M``@0$$B`2,`@;0`($(!2K0`(8+1,WT`,3EU.=4Y5__A(YS`"("T`#
  722. M#.6`*T#__$*M__A@&B!M__S1[?_X("W_^")M``@3J``!"`!2K?_X(&W__!`0Q
  723. M2(!(P"(M__BR@&W4("W_^"!M``A",`@`3-]`#$Y=3G5.5?[$2.<P`B!Y````@
  724. M""MH`"+__"!M__P@*``8Y8`K0/_X(&W_^"`H``3E@"M`__1@``&>(&W_]$JHK
  725. M``1F``&&(&W_]"\H`"A(;?_43KK_6E!/2&W_U"\M``A.N0``$TQ03TJ`9@`!:
  726. M7B!M__0@*``<Y8`K0/_P2JW_\&<``4A(>0`!``!(>``P3KD``"@^4$\K0/[,*
  727. M(&W_\"`H``3E@"M`_L@@;?[($!!(@$C`4H`K0/[$0J<O+?[$3KD``"@^4$\@3
  728. M;?[,((`@;?_P+R@`!"!M_LPO$$ZZ_M)03R!M__`B;?[,(U``!"!M__`B;?[,<
  729. M(V@`#``((&W_\"`H``CE@"M`_^P@;?[,(FW_["`I``3E@"%```P@;?_L(FW^;
  730. MS"-H``P`$"!M_^PB;?[,(V@`%``4(&W_[")M_LPC:``8`!@@;?_L(FW^S"-H?
  731. M`!P`'"!M_^PB;?[,(V@`)``@(&W_[")M_LPC:``H`"0@;?_L#)`````,91`@U
  732. M;?_L(FW^S"-H`#``*&`,(&W^S"%\`````@`H(&W_[`R0````$&40(&W_[")M^
  733. M_LPC:`!``"Q@#"!M_LPA?$1/4P``+"`M_LQ,WT`,3EU.=2!M__0@$.6`*T#_N
  734. M]$JM__1F`/Y><`!@X$Y5``!(YS`"0KD````,3-]`#$Y=3G5.50``2.<P`B/\C
  735. M`````0````Q,WT`,3EU.=4Y5``!(YS`"0J="ITZY```I%E!/P+P``#``9P1PT
  736. M`6`"<`!,WT`,3EU.=4Y5__Y(YS@B#+D````!````6&9L(#D```!4L*T`"&PL[
  737. M(#D```!4Y8`@;0`,(G`(``P1`"UF%B`Y````5.6`(&T`#")P"`!**0`!9@IPD
  738. M_TS?1!Q.74YU2'H"4"`Y````5.6`(&T`#"\P"`!.N0``$TQ03TJ`9@I2N0``H
  739. M`%1P_V#.(#D```!4Y8`@;0`,(C`(`"!Y````6!`P&`!(@$C`*``CP````!"XB
  740. MO````#IG%B\$+RT`$$ZY```3,E!/)$!*@&8``*9*N0```%!G9!M$__X;?``*2
  741. M__\@;0`,+Q!.N0``$4Q83R\`(&T`#"\02'@``DZY```BMD_O``Q(>@'$3KD`A
  742. M`!%,6$\O`$AZ`:%(>``"3KD``"*V3^\`#$AX``)(;?_^2'@``DZY```BMD_O5
  743. M``P@.0```%3E@"!M``PB,`@`4KD```!8('D```!82C`8`&804KD```!4(_P`K
  744. M```!````6'`_8`#^Z%**#!(`.F8``/H@.0```%3E@"!M``PB<`@`T_D```!8+
  745. M2BD``6<H(#D```!44KD```!4Y8`@;0`,(C`(`-*Y````6%*!(\$````48```U
  746. MJE*Y````5"`Y````5+"M``AM?$JY````4&=D&T3__AM\``K__R!M``PO$$ZY\
  747. M```13%A/+P`@;0`,+Q!(>``"3KD``"*V3^\`#$AZ`/=.N0``$4Q83R\`2'H`K
  748. MQTAX``).N0``(K9/[P`,2'@``DAM__Y(>``"3KD``"*V3^\`#"/\`````0``Q
  749. M`%AP/V``_@P@.0```%12N0```%3E@"!M``PC\`@`````%"/\`````0```%A@"
  750. M."`Y````5.6`(&T`#"(P"`!2N0```%@@>0```%A*,!@`9A`C_`````$```!81
  751. M4KD```!40KD````4(`1@`/VH+2T`.B!I;&QE9V%L(&]P=&EO;B`M+2``.B!I[
  752. M;&QE9V%L(&]P=&EO;B`M+2``.B!O<'1I;VX@<F5Q=6ER97,@86X@87)G=6UE7
  753. M;G0@+2T@`#H@;W!T:6]N(')E<75I<F5S(&%N(&%R9W5M96YT("TM(```(&\`:
  754. M!"`((F\`"!#99OQ.=2!O``0@"$H89OR1P"`(4X!.=7``$"\`![`\`&!C"K`\\
  755. M`'IB!)`\`"!.=7``$"\`![`\`$!C"K`\`%IB!-`\`"!.=4Y5``!(YS@B)&T`V
  756. M""\*3KD``!'2*`"PO/____]83V<@(`1@%%.2".H``P`,</],WT0<3EU.=6#4#
  757. M2H!G^EF`9^0@!&#J3E4``$CG,"(D;0`((%*QZ@`$90XO"F$<6$],WT0,3EU./
  758. M=2!24I(0$$B`2,#`O````/]@YDY5``!(YS@R)&T`"!`J``S`/``89PIP_TS?V
  759. M3!Q.74YU"*H``@`,2JH`"&8*+PI.N0``(+I83Q`J``Q(@$C`"```!V<\0?D`%
  760. M``#P)D@0*P`,2(!(P,"\````A+"\````A&8.2'C__R\+3KD``!^`4$_7_```I
  761. M`!9!^0```JBWR&7,,"H`$$C`+P`O*@`($"H`#4B`2,`O`$ZY```3?"@`2H!/)
  762. M[P`,;A1*A&8$<`A@`G`0@2H`#'#_8`#_8"2J``@@:@`(T<0E2``$(%)2DA`08
  763. M2(!(P,"\````_V``_SY.50``2.<P`B/M``@`````2&T`$"\M``Q(>@`43KD`.
  764. M`!GX3^\`#$S?0`Q.74YU3E4``$CG,`(O.0`````O+0`(3KD``!XN4$],WT`,Y
  765. M3EU.=2!O``0@+P`($AAG"K(`9O@@"%.`3G5P`$YU,#Q__V`$,"\`#E-`:Q0@A
  766. M;P`$(F\`"+$)9@Q32$H85\C_]G``3G5C!'`!3G5P_TYU3E4``$CG/"(H+0`(6
  767. M3KD``"-,<@8@!$ZY```EM"1`U?D````82H1M$#`Y```"J$C`N(!L!$J29A0C#
  768. M_`````(````<</],WT0\3EU.=3`J``1(P,"\`````["\`````68.(_P````%,
  769. M````''#_8-8O+0`0+RT`#"\23KD``"8^*@"PO/____]/[P`,9A!.N0``)@PCO
  770. MP````!QP_V"H(`5@I&%\0_D```*T1?D`````M<EF#C(\`!AK"'0`(L)1R?_\A
  771. M(\\````@+'@`!"/.````)$CG@(`(+@`$`2EG$$OZ``A.KO_B8`9"I_-?3G-#H
  772. M^@`D3J[^:"/`````"&8,+CP``X`'3J[_E&`&3KD``!2B4$].=61O<RYL:6)R"
  773. M87)Y`$GY``!__DYU3E4``$CG,")(>0`!```P.0```JC!_``&+P!.N0``*$0C/
  774. MP````!A03V880J=(>0`!``!.N0``)G)03RYY````($YU('D````80F@`!"!Y@
  775. M````&#%\``$`$"!Y````&#%\``$`"B!Y````("`Y````()"H``10@"/`````@
  776. M*"!Y````*""\34%.6$*G3KD``"AR)$!*J@"L6$]G."\M``PO+0`(+PI.N0``9
  777. M%BPC_`````$````,('D````8`&B````$('D````8`&B````*3^\`#&!62&H`@
  778. M7$ZY```I+$AJ`%Q.N0``*+`CP````"P@>0```"Q*J``D4$]G%"!Y````+")HX
  779. M`"0O$4ZY```EYEA/+SD````L+PI.N0``&'HC^0```"P````P4$].N0``)@(@I
  780. M>0```!@@@$ZY```F-"!Y````&"%```9G&DAX`^U(>@`Z3KD``"8D('D````89
  781. M(4``#%!/+SD````P+SD````T3KD```9B0J=.N0``(\)/[P`,3-]$#$Y=3G4JA
  782. M`$Y5``!(YSPR)&T`$"!M``A*J`"L9Q@@;0`(("@`K.6`*``@1"`H`!#E@"9`P
  783. M8`8F>0```JH0$TB`2,#0K0`,5(`CP````#A"IR\Y````.$ZY```H1"/`````[
  784. M/%!/9@A,WTP\3EU.=1`32(!(P"H`+P4@2U*(+P@O.0```#Q.N0``&%@@>0``K
  785. M`#S1Q4/Z`700V6;\+RT`#"\*+SD````\3KD``!@T('D````\0C!8`"/\````E
  786. M`0```#0@>0```#S1Q29(4HLD2T_O`!@0$TB`2,`J`+"\````(&<@NKP````)?
  787. M9QBZO`````QG$+J\````#6<(NKP````*9@12BV#,#!,`(&T``(X,$P`B9C)2"
  788. MBR!+4HL0$$B`2,`J`&<@($I2BA"%NKP````B9A`,$P`B9@12BV`&0BK__V`"7
  789. M8-)@1"!+4HL0$$B`2,`J`&<PNKP````@9RBZO`````EG(+J\````#&<8NKP`Q
  790. M```-9Q"ZO`````IG""!*4HH0A6#"($I2BD(02H5F`E.+4KD````T8`#_.D(2)
  791. M0J<@.0```#12@.6`+P!.N0``*$0CP````#!03V8*0KD````T8`#^I'H`)GD`[
  792. M```\8"`@!>6`('D````P(8L(`"!+(`A*&&;\D<!3B%*(U\A2A;JY````-&W8"
  793. M(`7E@"!Y````,$*P"`!@`/Y@(``P/'__8`0P+P`.(&\`!$H89OQ32")O``A3$
  794. M0!#95\C__&<"0A`@+P`$3G5,[P,```0@""(O``Q@`A#95\G__&<&4D%@`D(8]
  795. M4<G__$YU3E4``$CG/C(D;0`(0J=(>@"D3KD``"CH(\````!`4$]F"$S?3'Q.*
  796. M74YU(&T`#")H`"0O*0`$3KD``"E8*`!83V=:2'H`?2!$+R@`-DZY```I.B9`;
  797. M2H!03V<X2'@#[2\+3KD``"8D+`!03V<F(`;E@"H`($4E:``(`*0E1@"<2'@#X
  798. M[4AZ`$1.N0``)B0E0`"@4$\O!$ZY```I2EA/+SD```!`3KD``"::0KD```!`F
  799. M6$]@`/]P:6-O;BYL:6)R87)Y`%=)3D1/5P`J`$Y5``!(YS`"2&T`#"\M``A(U
  800. M>0``'@Q.N0``&?A/[P`,3-]`#$Y=3G5.50``2.<X(B1M`!`,K0````0`%&8(V
  801. M(&T`""@08!1*K0`,;P@@;0`(*!!@!B!M``@H$$*M`!1*K0`,;!)$K0`,2H1LV
  802. M"D2$*WP````!`!0B+0`,(`1.N0``':9!^0```%Q3BA2P"``B+0`,(`1.N0``<
  803. M';(H`&;82JT`%&<&4XH4O``M(`I,WT0<3EU.=4Y5_Q1(YS@R)&T`""9M``Q"S
  804. MK?_X*VT`$/_\($M2BQ`02(!(P"@`9P`#/+B\````)68``Q9"+?\B*WP````!=
  805. M__0K?````"#_\"M\```G$/_L($M2BQ`02(!(P"@`L+P````M9A!"K?_T($M2`
  806. MBQ`02(!(P"@`N+P````P9A0K?````##_\"!+4HL0$$B`2,`H`+B\````*F8:%
  807. M(&W__%BM__PK4/_H($M2BQ`02(!(P"@`8#A"K?_H8"1R"B`M_^A.N0``);30<
  808. MA)"\````,"M`_^@@2U*+$!!(@$C`*`!!^0```&\(,``"2`!FSKB\````+F9F_
  809. M($M2BQ`02(!(P"@`L+P````J9AH@;?_\6*W__"M0_^P@2U*+$!!(@$C`*`!@D
  810. M.$*M_^Q@)'(*("W_[$ZY```EM-"$D+P````P*T#_["!+4HL0$$B`2,`H`$'YJ
  811. M````;P@P``)(`&;.*WP````$_^2XO````&QF%B!+4HL0$$B`2,`H`"M\````6
  812. M!/_D8!2XO````&AF#"!+4HL0$$B`2,`H`"`$8```@BM\````"/_@8!PK?````
  813. M``K_X&`2*WP````0_^!@""M\____]O_@+RW_Y$AM_R(O+?_@+RW__$ZZ_:0K-
  814. M0/_<("W_Y-&M__Q/[P`08%P@;?_\6*W__")0*TG_W"`)2AEF_)/`4XDK2?_D+
  815. M8$H@;?_\6*W__"@00>W_(2M(_]P0A&`HD+P```!C9^)3@&>2D+P````+9P#_C
  816. M;%F`9[)5@&<`_VQ7@&<`_W!@S$'M_R*1[?_<*TC_Y"`M_^2PK?_L;P8K;?_L,
  817. M_^1*K?_T9W`@;?_<#!``+6<*(&W_W`P0`"MF-`RM````,/_P9BI3K?_H(&W_J
  818. MW%*M_]P0$$B`2,`O`$Z2L+S_____6$]F"G#_3-],'$Y=3G5@&"\M__!.DK"\S
  819. M_____UA/9@1P_V#B4JW_^"`M_^A3K?_HL*W_Y&[:0JW_X&`D(&W_W%*M_]P0[
  820. M$$B`2,`O`$Z2L+S_____6$]F!'#_8*I2K?_@(&W_W$H09PH@+?_@L*W_[&W*=
  821. M("W_X-&M__A*K?_T9BI@&DAX`"!.DK"\_____UA/9@9P_V``_W!2K?_X("W_0
  822. MZ%.M_^BPK?_D;MA@&"\$3I*PO/____]83V8&</]@`/](4JW_^&``_+@@+?_X_
  823. M8`#_.$CG2`!"A$J`:@1$@%)$2H%J!D2!"D0``6$^2D1G`D2`3-\`$DJ`3G5(A
  824. MYT@`0H1*@&H$1(!21$J!:@)$@6$:(`%@V"\!81(@`2(?2H!.=2\!808B'TJ`+
  825. M3G5(YS``2$%*068@2$$V`30`0D!(0(##(@!(0#("@L,P`4)!2$%,WP`,3G5(?
  826. M028!(@!"04A!2$!"0'0/T(#3@;:!8@22@U)`4<K_\DS?``Q.=4Y5``!(YS`"5
  827. M2'D```$&+RT`"$ZY```>+E!/3-]`#$Y=3G5.50``2.<X`B@M``@O+0`,+P1.5
  828. MN0``'GRXO`````I03V8J(&T`#!`H``Q(@$C`"```!V<82'C__R\M``Q.N0``H
  829. M'X!03TS?0!Q.74YU8/9.50``2.<P(B1M``P@4K'J``1E'"`M``C`O````/\O;
  830. M`"\*3KH`X%!/3-]$#$Y=3G4@4E*2$"T`"Q"`2(!(P,"\````_V#B3E4``$CGV
  831. M,")!^0```/`D2"!*U?P````6+PAA%%A/0?D```*HM<AEZ$S?1`Q.74YU3E4`&
  832. M`$CG."(D;0`(>``@"F8*</],WT0<3EU.=4HJ``QG6@@J``(`#&<,2'C__R\*'
  833. M85PH`%!/$"H`#4B`2,`O`$ZY```E5(B`""H``0`,6$]G#"\J``A.N0``(;Y8*
  834. M3P@J``4`#&<6+RH`$DZY```BA"\J`!).N0``(;Y03T*20JH`!$*J``A"*@`,'
  835. M(`1@ADY5__Y(YS@B)&T`"$'Z_S0CR````$0(*@`$``QG"G#_3-]$'$Y=3G4(,
  836. M*@`"``QG-B!2D>H`""@(+P0O*@`($"H`#4B`2,`O`$ZY```BMK"$3^\`#&<0H
  837. M".H`!``,0I)"J@`$</]@N@RM_____P`,9A`(J@`"``Q"DD*J``1P`&"@2JH`N
  838. M"&8*+PI.N0``(+I83PQJ``$`$&8R&VT`#___2'@``4AM__\0*@`-2(!(P"\`G
  839. M3KD``"*VL+P````!3^\`#&:4("T`#&``_U@DJ@`(,"H`$$C`T*H`""5```0(;
  840. MZ@`"``P@4E*2$"T`#Q"`2(!(P,"\````_V``_RA.50``2.<P(D'Y````\"1(V
  841. M2BH`#&<<U?P````60?D```*HM<AE"G``3-]$#$Y=3G5@WD*20JH`!$*J``@@I
  842. M"F#H3E7__$CG,"(D;0`(2'@$`$ZY```AIBM`__Q83V8:-7P``0`0($K1_```B
  843. M``XE2``(3-]$#$Y=3G4U?`0``!`(Z@`!``PE;?_\``@0*@`-2(!(P"\`3KD`2
  844. M`"(02H!83V<&`"H`@``,8,A.50``2.<P,B1Y````!&`6)E(@*@`$4(`O`"\*W
  845. M3KD``"B04$\D2R`*9N9"N0````1,WTP,3EU.=4Y5``!(YS`B0?K_OB/(````Z
  846. M2$*G("T`"%"`+P!.N0``*$0D0$J`4$]F"G``3-]$#$Y=3G4DN0````0E;0`()
  847. M``0CR@````0@"E"`8.!.50``2.<P`B\M``AAIEA/3-]`#$Y=3G5.50``2.<PL
  848. M,I?+)'D````$8`X@;0`(48BQRF<2)DHD4B`*9NYP_TS?3`Q.74YU(`MG!":27
  849. M8`8CT@````0@*@`$4(`O`"\*3KD``"B0<`!03V#43E4``$CG,")R!B`M``A.F
  850. MN0``);0D0-7Y````&$JM``AM%#`Y```"J$C`(BT`"+*`;`1*DF84(_P````"G
  851. M````''#_3-]$#$Y=3G5R!B`M``A.N0``);0@>0```!@O,`@`3KD``"862H!8>
  852. M3V<$<`%@`G``8,Y.50``2.<P`B\M``A.N0``)?1*@%A/9A9.N0``)@PCP```\
  853. M`!QP_TS?0`Q.74YU<`!@]$Y5``!(YSPB*"T`"$ZY```C3'(&(`1.N0``);0D7
  854. M0-7Y````&$J$;1`P.0```JA(P+B`;`1*DF84(_P````"````''#_3-]$/$Y=,
  855. M3G4P*@`$P'P``V8.(_P````%````''#_8.`O+0`0+RT`#"\23KD``"9B*@"P!
  856. MO/____]/[P`,9A!.N0``)@PCP````!QP_V"R(`5@KDY5__Q(YS`"2'@0`$*G<
  857. M3KD``"D<*T#__`@```Q03V<:2KD````,9@P@+?_\3-]`#$Y=3G5.N0``(XIPX
  858. M`&#N3E4``$CG,`)(>``$2'H`)DZY```F-"\`3KD``"9B2'@``4ZY```CPD_O(
  859. M`!!,WT`,3EU.=5Y#"@!.50``2.<P`DJY````1&<(('D```!$3I`O+0`(3KD``
  860. M`"/N6$],WT`,3EU.=4Y5__Q(YS@"*VT`"/_\2KD````89S9X`&`,+P1.N0``5
  861. M)5183U*$,#D```*H2,"X@&WH,#D```*HP?P`!B\`+SD````83KD``"B04$]*+
  862. MN0```$AG""!Y````2$Z02KD```*N9PXO.0```JY.N0``)DY83TJY````3&<,3
  863. M('D```!,(+D```!02KD```!49PXO.0```%1.N0``)J!83TJY````6&<.+SD`"
  864. M``!83KD``":@6$]*N0```%QG#B\Y````7$ZY```FH%A/2KD```!@9PXO.0``8
  865. M`&!.N0``)J!83RQX``0(+@`$`2EG%"\-2_H`"DZN_^(J7V`&0J?S7TYS2KD`Q
  866. M```L9CA*N0```#QG+B\Y````."\Y````/$ZY```HD"`Y````-%*`Y8`O`"\Y\
  867. M````,$ZY```HD$_O`!!@%$ZY```H@"\Y````+$ZY```I"%A/("W__"YY````"
  868. M($YU3-]`'$Y=3G5.50``2.<^(B@M``AR!B`$3KD``"6T)$#5^0```!A*A&T0X
  869. M,#D```*H2,"X@&P$2I)F%"/\`````@```!QP_TS?1'Q.74YU,"H`!,!\@`!F>
  870. M"B\23KD``"786$]"DG``8-Y(YW``-`'$P"8!2$/&P$A#0D/4@TA`P,%(0$)`"
  871. MT(),WP`.3G4B+P`$+'D````(3N[_W"(O``0L>0````A.[O^"(B\`!"QY````@
  872. M"$[N_[@L>0````A.[O_*+'D````(3N[_?"(O``0L>0````A.[O\H3.\`!@`$[
  873. M+'D````(3N[_XBQY````"$[N_\1,[P`.``0L>0````A.[O_63OD``"94(B\`3
  874. M!"QY````"$[N_Z9,[P`.``0L>0````A.[O_02.<!!$SO((``#"QY````)$ZNW
  875. M_Y1,WR"`3G4B;P`$+'D````D3N[^/D[Y```FH")O``0L>0```"1.[OYB3E4`A
  876. M`$CG.")(>/__3KD``">D*`"PO/____]83V8*<`!,WT0<3EU.=4AY``$``4AXL
  877. M`").N0``*#XD0$J`4$]F#B\$3KD``"BB<`!83V#2)6T`"``*%6T`#P`)%7P`L
  878. M!``(0BH`#A5$``]"ITZY```H;"5``!!*K0`(6$]G#"\*3KD``">66$]@#$AJ"
  879. M`!1.N0``*+Y83R`*8(A.50``2.<P(B1M``A*J@`*9PHO"DZY```H^EA/%7P``
  880. M_P`()7S_____`!1P`!`J``\O`$ZY```HHDAX`"(O"DZY```HBD_O``Q,WT0,*
  881. M3EU.=2)O``0L>0```"1.[OZ>("\`!"QY````)$[N_K9.50``2.<P(DJM``AFY
  882. M"G``3-]$#$Y=3G5(>0`!``$O+0`,3KD``"@^)$!*@%!/9@1P`&#<%7P`!0`(\
  883. M-6T`#@`2)6T`"``.(`I@QDY5``!(YS`B)&T`""`*9@A,WT0,3EU.=15\`/\`(
  884. M""5\_____P`4)7S_____`!AP`#`J`!(O`"\*3KD``"B*4$]@SD[Y```H1$SOF
  885. M``,`!"QY````)$[N_SI(YP,`(F\`#"QY````)$ZN_CA,WP#`3G5.^0``*'(B`
  886. M;P`$+'D````D3N[^VBQY````)$[N_WQ.^0``*)`B;P`$("\`""QY````)$[N`
  887. M_RX@+P`$+'D````D3N[^L"!O``0L>0```"1.[OZ,(&\`!""(6)!"J``$(4@`/
  888. M"$YU(&\`!$SO`@$`""(O`!`L>0```"1.[OY$+'D````D(F\`!"`O``A.[OW82
  889. M(F\`!"QY````)$[N_I@B;P`$+'D````D3N[^AD[Y```I'$SO``,`!"QY````!
  890. M)$[N_LX@;P`$+'D````D3N[^@$SO`P``!"QY````0$[N_Z`@;P`$+'D```!`\
  891. M3N[_IB!O``0L>0```$!.[O^R``````/L````1`````$```'B```"&@```Z``<
  892. M``/<```#Y```!"8```8H```&<@``!K````:X```&O@``!OP```<B```(Y```E
  893. M"U0```XP```..```#D0```Y:```.?@``#IH```ZD```.M```#N@```]4```/M
  894. M9```#VH```]V```/@```#Y8```^F```/L@``#[@```_(```/V@``#^````_L]
  895. M```07```$&@``!!N```0A@``$(X``!">```0I```$+0``!"Z```23```$GX`T
  896. M`!.F```4(```%)P``!2R```67```&<@``!K6```;1```'A8``![,```>X@``C
  897. M((0``""8```B-```(N```"06```D(@``)$P``"14```E>````+(````````!L
  898. MK@```=0```(N```"/````G(```*$```"F````JH```+&```"Z@```OP```,:`
  899. M```#=@```[@```/2```$#```!!H```0L```$-```!$(```1.```$G```!+8`1
  900. M``32```$X@``!/0```8N```&;```!GP```:0```&T@``!MP```<0```'&@``D
  901. M!S8```="```'<@``!WX```><```'N@``!]@```?V```($@``""````@Z```(0
  902. M2```"%0```AR```(E@``"*0```C.```(W```".H```D6```)(@``"3@```E(P
  903. M```)5@``"5X```EH```+;@``#$@```QV```,I@``#@8```Z.```.V```#P``=
  904. M``\4```/(@``#S0```]*```0!```$!@``!`F```0.```$$X``!&>```2-@``_
  905. M$G```!*>```3````$R0``!.*```3E```$_8``!0*```4A@``%+X``!36```52
  906. M+@``%4@``!5Z```5A```%:H``!6Z```5S```%=H``!7T```6$@``%AH``!9\$
  907. M```6J@``%LP``!?0```8C@``&+(``!C(```8W```&0(``!D0```9'@``&58`W
  908. M`!E<```9P@``&=H``!JX```;)@``'B```!Y"```>;```'S0``!]*```?7@``W
  909. M'V@``!_*```@"@``(#(``"#,```A$```(4```"%X```B!@``(B```")B```B3
  910. M<@``(I(``"*>```BQ```(LX``",F```C.@``(UP``"."```CG```(Z0``".N=
  911. M```CX```)`P``"0T```D6@``)(0``"2:```DL```),8``"4*```E(@``)2X`V
  912. M`"4Z```E9@``):@``"90```FG```)KP``";B```F\@``)QH``"<N```G/```J
  913. M)UP``"=Z```GA@``)]8``"@V```H0```*&X``"B,```I&````(@````"```+T
  914. M]@``#=(```WL```.Q```#]```!!\```0P```$NX``!,:```3G```$[H``!/BY
  915. M```4$```%"8``!0^```42```%'(``!3$```4W@``%.8``!3P```4_```%0@`'
  916. M`!4.```5&@``%2```!52```56```%60``!6*```5D```%9X``!6R```5P```G
  917. M%<0``!72```5X```%?H``!8&```6#```%FX``!9V```6@@``%J0``!:P```6`
  918. MQ@``%M(``!;@```6Y@``%[8``!?$```7U@``%^```!?L```7^```&!0``!@@B
  919. M```8E```&1@``!DD```?D@``(2P``"%.```A:```(9```"&<```AR@``(?8``
  920. M`"(H```B3```(F@``"*D```BU@``(O0``",2```C0```(VX``"/,```CU```E
  921. M(_X``"0N```D/```)$0``"1B```D:@``)'```"1V```D?@``)(P``"24```DK
  922. MH@``)*H``"2X```DP```).X``"3V```D_@``)00``"40```E'```)30``"5&A
  923. M```E;@``)8P``"7>```E[```)?H``"8$```F#@``)AP``"8L```F-@``)D8`Q
  924. M`"9:```F:@``)GX``":2```FI@``)YP``">J```H3```*%X``"AX```H@@``0
  925. M*)H``"BH```HM@``*.```"CJ```I````*0X``"DD```I,@``*4(``"E0```I?
  926. M7@````````/R```#Z@```*TQ+C``````!````!<````S````3````&<```"!^
  927. M````H````,4```#B````^@```18```$_```!40```6$```%P```!?0``````[
  928. M`````````0````$````!`````3`Q,C,T-38W.#EA8F-D968````@("`@("`@&
  929. M("`P,#`P,"`@("`@("`@("`@("`@("`@()!`0$!`0$!`0$!`0$!`0$`,#`P,P
  930. M#`P,#`P,0$!`0$!`0`D)"0D)"0$!`0$!`0$!`0$!`0$!`0$!`0$!0$!`0$!`2
  931. M"@H*"@H*`@("`@("`@("`@("`@("`@("`@)`0$!`(``````````````````!%
  932. M``````$``````````````````````0$````!``````````````````````$"'
  933. M`````0``````````````````````````````````````````````````````!
  934. M`````````````````````````````````````````````````````````````
  935. M`````````````````````````````````````````````````````````````
  936. M`````````````````````````````````````````````````````````````
  937. M`````````````````````````````````````````````````````````````
  938. M`````````````````````````````````````````````````````````````
  939. M`````````````````````````````````````````````````````````````
  940. M`````````````````````````````````````````````````````````````
  941. M```````````````````````````````4`````````````````^P````0````3
  942. M``````0````(````#````!`````4````&````!P````@````)````"@````L(
  943. H````,````#0````X````/````$`````````#\@```^L````9```#\B@`Q
  944. ``
  945. end
  946. size 13000
  947. SHAR_EOF
  948. #    End of shell archive
  949. exit 0
  950. -- 
  951. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  952. Have five nice days.
  953.